package net.alan.modules.service.impl;

import net.alan.common.constants.EProjectLogType;
import net.alan.common.utils.MD5Util;
import net.alan.modules.bean.*;
import net.alan.modules.cache.WebContextUtil;
import net.alan.modules.handle.BaseExecption;
import net.alan.modules.repository.*;
import net.alan.modules.service.IChatService;
import net.alan.modules.service.IProjectService;
import net.alan.modules.service.IUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * Author 李岩飞
 * Email eliyanfei@126.com
 * 2017/11/21
 */
@Service
public class UserServiceImpl extends BaseServiceImpl implements IUserService {
    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
    @Autowired
    private ProjectRepository projectRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private UserLogRepository userLogRepository;
    @Autowired
    private UserProjectRepository userProjectRepository;
    @Autowired
    private UserStatRepository userStatRepository;
    @Autowired
    private WorkStatRepository workStatRepository;
    @Autowired
    private IProjectService projectService;
    @Autowired
    private IChatService chatService;

    @Override
    public JpaRepository getJpaRepository(Class<?> cla) {
        if (isSame(cla, User.class)) {
            return userRepository;
        } else if (isSame(cla, UserLog.class)) {
            return userLogRepository;
        } else if (isSame(cla, UserProject.class)) {
            return userProjectRepository;
        } else if (isSame(cla, UserStat.class)) {
            return userStatRepository;
        } else if (isSame(cla, WorkStat.class)) {
            return workStatRepository;
        } else if (isSame(cla, Project.class)) {
            return projectRepository;
        }
        return null;
    }

    @Override
    public Result editMaxProject(Integer id, Integer maxProject) {
        try {
            User user = getById(User.class, id);
            user.setMaxProject(maxProject);
            userRepository.save(user);
        } catch (Exception e) {
            return ResultUtil.error("");
        }
        return ResultUtil.success();
    }

    @Override
    public Result editUser(User newuser) {
        try {
            User user = getById(User.class, WebContextUtil.getUserId());
            user.setName(newuser.getName());
            user.setEmail(newuser.getEmail());
            user.setSex(newuser.getSex());
            user.setSign(newuser.getSign());
            user.setPhone(newuser.getPhone());
            user = userRepository.save(user);
            WebContextUtil.getCurrentUser().setUser(user);
            WebContextUtil.userMap.put(user.getId(), user.getName());
        } catch (Exception e) {
            return ResultUtil.error("");
        }
        return ResultUtil.success();
    }

    @Override
    public Result editPass(String oldpassword, String password) {
        User user = getById(User.class, WebContextUtil.getUserId());
        if (user.getPassword().equals(MD5Util.md5(oldpassword))) {
            user.setPassword(MD5Util.md5(password));
            userRepository.save(user);
            return ResultUtil.success();
        } else {
            return ResultUtil.error("原密码错误");
        }
    }

    @Override
    public Result resetPass(String email, String password) {
        User user = getUserByEmail(email);
        if (user == null)
            return ResultUtil.error("网络错误，请重新尝试！");
        user.setPassword(MD5Util.md5(password));
        this.userRepository.save(user);
        return ResultUtil.success();
    }

    @Override
    public Result addUser(User user) {
        User u = getUser(user.getAccount(), false);
        if (u == null) {
            user = this.userRepository.save(user);
            WebContextUtil.userMap.put(user.getId(), user.getName());
        } else {
            return ResultUtil.error("该用户已经存在");
        }
        return ResultUtil.success();
    }

    @Override
    public User getUserByEmail(String email) {
        User user = null;
        try {
            user = this.userRepository.findByEmail(email);
            user.toString();
            return user;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public User getUser(String account, boolean login) {
        User user = userRepository.findByAccount(account);
        if (user != null) {
            user.setLastLogin(new Date());
            this.userRepository.save(user);
        }
        return user;
    }

    @Override
    public Page<UserLog> findUserLogByUserId(Integer userId, PageModel pageModel) {
        return this.userLogRepository.findByUserId(userId, pageModel.getPageable());
    }

    @Override
    public Page<UserLog> findUserLog(PageModel pageModel) {
        return this.userLogRepository.findAll(pageModel.getPageable());
    }

    @Override
    public List<UserProject> findUserProjectByProjectId(Integer projectId) {
        return this.userProjectRepository.findByProjectId(projectId);
    }

    @Override
    public Integer countUserProjectByProjectId(Integer projectId) {
        return this.userProjectRepository.countByProjectId(projectId);
    }

    /**
     * 需要判断是否已经加入
     *
     * @param userProject
     * @return
     */
    @Override
    public Result addUserProject(UserProject userProject) {
        UserProject u = this.userProjectRepository.findByProjectIdAndUserId(userProject.getProjectId(), userProject.getUser().getId());
        if (u == null) {
            List<UserProject> userList = this.userProjectRepository.findByProjectId(userProject.getProjectId());
            if (userList != null) {
                Integer userId = userProject.getUser().getId();
                for (UserProject up : userList) {
                    try {
                        Chat chat = new Chat();
                        chat.setReaded(false);
                        chat.setProjectId(userProject.getProjectId());
                        chat.setUserId(userId);
                        chat.setToUserId(up.getUser().getId());
                        chatService.save(Chat.class, chat);
                    } catch (BaseExecption baseExecption) {
                    }
                    try {
                        Chat chat = new Chat();
                        chat.setReaded(false);
                        chat.setProjectId(userProject.getProjectId());
                        chat.setUserId(up.getUser().getId());
                        chat.setToUserId(userId);
                        chatService.save(Chat.class, chat);
                    } catch (BaseExecption baseExecption) {
                    }
                }
            }
            this.userProjectRepository.save(userProject);

            Project project = this.projectRepository.getOne(userProject.getProjectId());
            project.setUsers(countUserProjectByProjectId(project.getId()));
            this.projectRepository.save(project);
            this.projectService.addProjectLog(userProject.getProjectId(), EProjectLogType.userAdd, "加入项目");
        } else {
            return ResultUtil.error("您已经加入项目");
        }
        return ResultUtil.success();
    }

    @Override
    public Page<User> findByAccountOrName(String search, PageModel pageModel) {
        return this.userRepository.findByAccountOrName(search, search, pageModel.getPageable());
    }

    @Override
    public Page<UserStat> findUserStat(PageModel pageModel) {
        return this.userStatRepository.findAll(pageModel.getPageable(Sort.Direction.DESC, "day"));
    }

    @Override
    public List<WorkStat> findWorkStat() {
        return this.workStatRepository.findAll();
    }

    @Override
    public Result quitUserProject(Integer projectId) {
        Project project = projectRepository.findOne(projectId);
        if (project.getUser().getId() == WebContextUtil.getUserId()) {
            return ResultUtil.error("您是项目创建者，必须先移交项目后，然后可以退出项目");
        }
        this.userProjectRepository.deleteByProjectIdAndUserId(projectId, WebContextUtil.getUserId());
        this.projectService.addProjectLog(projectId, EProjectLogType.common, "退出项目");
        return ResultUtil.success();
    }

    @Override
    public Result deleteUserProject(Integer projectId, Integer userId) {
        Project project = projectRepository.findOne(projectId);
        Integer uId = WebContextUtil.getUserId();
        if (uId == userId) {
            return ResultUtil.error("不能移除自己");
        } else if (project.getUser().getId() == uId) {
            try {
                this.userProjectRepository.deleteByProjectIdAndUserId(projectId, userId);
                this.chatService.deleteChatByUserId(projectId,userId);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return ResultUtil.success();
        }
        return ResultUtil.noRole();
    }

    @Override
    public WorkStat getWorStat(String name) {
        return this.workStatRepository.findByName(name);
    }

    @Override
    public long getRegistersByLastLogin(Date date) {
        return this.userRepository.getRegistersByLastLogin(date).get(0).intValue();
    }

    @Override
    public long getLoginsByCreated(Date date) {
        return this.userRepository.getLoginsByCreated(date).get(0).intValue();
    }
}
